package com.hly.musicbackground.model.index.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hly.musicbackground.Enum.BannerEnum;
import com.hly.musicbackground.Final.RedisFinal;
import com.hly.musicbackground.Utils.DozerUtils;
import com.hly.musicbackground.Utils.RedisUtil;
import com.hly.musicbackground.Utils.RequestContextUtils;
import com.hly.musicbackground.dao.HomeDao;
import com.hly.musicbackground.domain.Banner;
import com.hly.musicbackground.domain.Home;
import com.hly.musicbackground.model.boots.service.FictionService;
import com.hly.musicbackground.model.boots.service.FictionShelfService;
import com.hly.musicbackground.model.index.VO.*;
import com.hly.musicbackground.model.index.params.EditHomeParams;
import com.hly.musicbackground.model.index.params.OtherParams;
import com.hly.musicbackground.model.index.service.BannerService;
import com.hly.musicbackground.model.index.service.HomeService;
import com.hly.musicbackground.model.index.service.SelectConditionService;
import com.hly.musicbackground.model.music.service.SongService;
import com.hly.musicbackground.model.user.service.UserLogService;
import com.hly.musicbackground.result.Code;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class HomeServiceImpl extends ServiceImpl<HomeDao, Home> implements HomeService {

    private final SongService songService;
    private final BannerService bannerService;
    private final FictionService fictionService;
    private final FictionShelfService fictionShelfService;
    private final UserLogService userLogService;
    private final RedisUtil redisUtil;
    private final SelectConditionService selectConditionService;
    private final DozerUtils dozerUtils;

    @Override
    public List<RecommendVO> getRecommend() {
        List<RecommendVO> recommendVOS =
        redisUtil.queryWithLogicalExpire(RedisFinal.HOME_GET_RECOMMEND, 1, List.class,
        this::getRecommend, 1L, TimeUnit.DAYS);
        if (recommendVOS != null){
            return recommendVOS;
        }
        recommendVOS = getRecommend(1);
        redisUtil.setWithLogicalExpire(RedisFinal.HOME_GET_RECOMMEND + 1, recommendVOS, 1L, TimeUnit.DAYS);
        return recommendVOS;
    }

    public List<RecommendVO> getRecommend(int n){

        ArrayList<RecommendVO> recommendVOS = new ArrayList<>();

        List<Home> list = getHomeList();// 获取目录

        list.forEach(y -> {

            // 轮播图
            List<Banner> banners = bannerService.getBannerList(y.getBanners());

            // 菜单
            List<Banner> menus = bannerService.getBannerList(y.getMenus());

            recommendVOS.add(RecommendVO.builder()
                    .menus(menus)
                    .banners(banners)
                    .list(fromHome(y))
                    .title(y.getTitle())
                    .type(y.getType()).build());
        });

        return recommendVOS;
    }

    public ArrayList<ListTitleVO> fromHome(Home y){

        // 二级菜单
        List<Home> homes = lambdaQuery().eq(Home::getSecondId, y.getHomeId())
                .eq(Home::getStatus, BannerEnum.SHOW.getValue()).list();

        ArrayList<ListTitleVO> listTitleVOS = new ArrayList<>();

        if (homes == null)
            return listTitleVOS;

        homes.forEach(l -> {

            List listData = null;

            listData = selectConditionService.getDataList(l.getHomeId(), l.getType());

            if (listData == null){
                listData = fromHome(l);
            }

            listTitleVOS.add(ListTitleVO.builder()
                    .select(selectConditionService.getQueryById(l.getHomeId(), l.getType()))
                    .list(listData)
                    .home(l)
                    .build());

        });
        return listTitleVOS;
    }


    @Override
    public LikeRecommendVO getLike(OtherParams otherParams) {
        ArrayList<LikeTitleVO> likeTitleVOS = new ArrayList<>();
        int userId = RequestContextUtils.getUser().getUserId();

        // redis权重缓存key
        String key = RedisFinal.HOME_GET_LIKE_WEIGHT + otherParams.getType() + ":";

        // 计算权重
        Map<String, Integer> weight = redisUtil.queryWithPassThrough(key, userId, Map.class,
                 this::countWeight, 10L, TimeUnit.MINUTES);

        // 获取排除名单

        // 根据权重随机获取数据
        Random random = new Random();
        for (int i = 0; i < 5; i++) {
            if (random.nextInt(10) != 0){
                // 按照类型获取
            }else {
                // 按照看过同作品的人获取
            }
        }

        return LikeRecommendVO.builder().like(likeTitleVOS).build();
    }

    public Map<String, Integer> countWeight(int i){
        HashMap<String, Integer> stringIntegerHashMap = new HashMap<>();
        return stringIntegerHashMap;
    }

    @Override
    public List<HomeVO> getDirectory() {
        List<Home> list = getHomeList();

        List<HomeVO> voList = dozerUtils.convert(list, HomeVO.class);

        voList.forEach(n -> {
            long count = lambdaQuery().eq(Home::getSecondId, n.getHomeId()).count();
            n.setSecondNum((int) count);
        });

        return voList;
    }

    public List<Home> getHomeList() {
        return lambdaQuery()
                .eq(Home::getStatus, BannerEnum.SHOW.getValue()).eq(Home::getSecondId, 0).list();
    }

    @Override
    public RecommendVO getDetail(int id) {
        RecommendVO build = redisUtil.queryWithPassThrough(RedisFinal.HOME_GET_DETAIL_ID, id, RecommendVO.class,
                i -> {
                    Home y = getById(i);
                    if (y == null)
                        Code.BUSINESS_ERR("该id不正确");
                    // 轮播图
                    List<Banner> banners = bannerService.getBannerList(y.getBanners());
                    // 菜单
                    List<Banner> menus = bannerService.getBannerList(y.getMenus());
                    RecommendVO vo = RecommendVO.builder()
                            .menus(menus)
                            .banners(banners)
                            .list(fromHome(y))
                            .title(y.getTitle())
                            .type(y.getType()).build();
                    return vo;
                }, 1L, TimeUnit.DAYS);
        return build;
    }

    @Override
    public void editHome(EditHomeParams params) {
        if (params.getHomeId() != 0){
            Home home = getById(params.getHomeId());
            if (home == null){
                Code.BUSINESS_ERR("没有该精选");
            }
            updateById(setEditHome(home, params));
        }else {
            save(setEditHome(new Home(), params));
        }
    }

    @Override
    public void delHomeByIdAll(int id) {

    }

    public Home setEditHome(Home home, EditHomeParams params){
        if (params.getSecondId() == 0){
            home.setBanners(BannerEnum.banners.getType() + params.getType());
            home.setMenus(BannerEnum.menus.getType() + params.getType());
        }else {
            home.setSecondId(params.getSecondId());
        }
        home.setType(params.getType());
        home.setTitle(params.getTitle());
        home.setStatus(params.getStatus());
        return home;
    }
}
